import { render } from 'vue'

/**
 * @author lyj
 * @description 仿react打开一个弹框的方法，只需要调用方法即可出现弹框，让vue文件的state中可以少定义两个字段。增强程序可读性
 * @param {*} component 弹框中包容的组件
 * @param {*} componentProps 弹框中组件的props
 * @param {*} userCloseFunction 监听弹框中组件emit的方法
 * @param {*} opts 弹框的一些配置
 * @example
 * openDialog(SubmitForm,{enterprisecode:'55555'},(closeDialog)=>{
      return {
        '@submit':(data)=>{
          alert("表单提交了")
          closeDialog()
        }
      }
    },{title:"我是标题",width:'60%',top:'10%',height:'70%'})
 */
export const openDialog = (component, componentProps = {}, componentEmits = ()=>{}, opts = {}) => {
    debugger
    //1.定义一个对象式vue弹框组件 
    const mydialog = {
        render:(ctx)=>{
            const { contentSlot, closeDialog, componentProps,eventList} =ctx.$attrs
            return (<div class="an-interesting-dialog">
                <div class="main" style={{ position: 'absolute', padding: '15px', left: '50%', transform: 'translateX(-50%)', top: '50px', height: '732px', width: '70%', background: '#f6f7f8', zIndex: '1000', ...ctx.$attrs }}>
                    <div class="header" style={{ height: '5%', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                        <div class="title" style={{ fontSize: '16px', fontWeight: 900 }} >{ctx.$attrs.title || '数据维护'}</div>
                        <div class="closebutton" onClick={() => closeDialog()} style={{ cursor: 'pointer', color: 'white', backgroundColor: "rgb(245,108,108)", padding: "2px 10px", borderRadius: "15%" }}>关闭</div>
                    </div>
                    <div class="content" style={{ height: '93%', overflow: 'auto' }}>
                        <contentSlot {...eventList} {...componentProps}></contentSlot>
                    </div>
                </div>
                <div
                    class="mask"
                    onClick={() => closeDialog()}
                    style={{
                        position: 'fixed',
                        top: 0,
                        left: 0,
                        height: '100vh',
                        width: '100vw',
                        background: '#555558',
                        opacity: '0.6',
                        zIndex: 999
                    }}
                />
            </div>)
        }
    }
    //2.声明一个关闭弹框的方法，该方法会在点击<遮罩层>或者<关闭按钮>时执行，也会将该方法传给参数component组件,
    const closeDialog = () => {
        debugger
        //2.1 添加消失动画
        let fade1 = document.querySelector('.an-interesting-dialog>.mask').animate([{ opacity: 0.6 }, { opacity: 0 }], { duration: 100, easing: "linear" })
        let fade2 = document.querySelector('.an-interesting-dialog>.main').animate([{ opacity: 1, transform: 'translate(-50%,0)' }, { opacity: 1, transform: 'translate(-50%,-10%)' }], { duration: 100, easing: "linear" })
        //2.2 当两个动画都执行完成之时,调用用户传过来的关闭弹框逻辑代码
        Promise.all([fade1.finished, fade2.finished]).then(_=> {
            vm = null
            container.remove()
        })
    }
    //3.将用户传来的参数中的监听项做处理 -----> @submit => onSubmit（JSX只能监听on开头的函数）
    const emitsEvent = componentEmits(closeDialog)
    const eventList = {}
    for(let key in emitsEvent){
        let c = key.substring(2)
        let b = key.charAt(1).toUpperCase()
        let a ='on'
        let keyResult = a+b+c;
        eventList[keyResult] = emitsEvent[key]
    }

    //4.根据用户传来的组件和参数，生成Vnode
    let vm = <mydialog {...opts} eventList={eventList} contentSlot={component} closeDialog={closeDialog} componentProps={componentProps}></mydialog>
    //5.创建一个真实dom
    const container = document.createElement('div')
    //6.将vnode挂载到真实dom上
    render(vm, container)
    //7.将真实dom添加到body上
    document.body.appendChild(container)
    //8.给弹框添加出现动画
    document.querySelector('.an-interesting-dialog>.main').animate([{ opacity: 0, transform: 'translate(-50%,-10%)' }, { opacity: 1, transform: 'translate(-50%,0)' }], { duration: 100, easing: "linear" })
}


//使用animate (异步API) 让dom执行一段动画：（与@keyFrames类似）
// let targetDom  = document.querySelector('.an-interesting-dialog>.main')
// let appearKeyFrames = [
//     {opacity: 0,transform: 'translate(-50%,-20%)'},
//     {opacity: 1,transform: 'translate(-50%,0)'}
// ]
// let appearTiming = {duration:1000,easing:"ease-in-out"}
// targetDom.animate(appearKeyFrames,appearTiming)//这种方式不同于@keyfram的方式，这种方式：在动画*期间*会替代原来的样式，但动画执行完成，会立马变成指定的样式，所以要保证appearKeyFrames最后一个对象要和样式一样，否则就会发生样式突变的情况